package org.light.domain;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.log4j.Logger;
import org.light.core.JumpHomePage;
import org.light.core.LayoutComb;
import org.light.core.ReportComb;
import org.light.easyuilayouts.widgets.Nav;
import org.light.exception.ValidateException;
import org.light.generator.CodeGoGenerator;
import org.light.generator.ConfigGoGenerator;
import org.light.generator.ConfigYamlGenerator;
import org.light.generator.CorsGenerator;
import org.light.generator.DBDefinitionGenerator;
import org.light.generator.DateTimeAndDateGoGenerator;
import org.light.generator.DateTimeUtilGenerator;
import org.light.generator.ErrorGoGenerator;
import org.light.generator.HandlerGenerator;
import org.light.generator.InitDBGenerator;
import org.light.generator.RouterGenerator;
import org.light.generator.ServerGoGenerator;
import org.light.generator.TwoDomainsDBDefinitionGenerator;
import org.light.layouts.EasyUIHomePagePI;
import org.light.layouts.EasyUIMtmPI;
import org.light.oracle.generator.Oracle11gSqlReflector;
import org.light.oracle.generator.OracleTwoDomainsDBDefinitionGenerator;
import org.light.simpleauth.LoginServiceImplGenerator;
import org.light.simpleauth.SimpleAuthModule;
import org.light.utils.PgsqlReflector;
import org.light.utils.SqlReflector;
import org.light.utils.StringUtil;
import org.light.utils.ZipCompressor;
import org.light.wizard.ExcelWizard;

import net.sf.json.JSONObject;

public class Project implements Serializable {
	private static final long serialVersionUID = 5684368331555485772L;
	protected static Logger logger = Logger.getLogger(Project.class);
	protected long projectId;
	protected String standardName;
	protected String packageToken;
	protected String technicalstack;
	protected long namingId;
	protected Naming naming;
	protected String folderPath = "D:/JerryWork/Infinity/testFiles/";
	protected String sourceFolderPath = "D:/JerryLunaWorkspace/InfinityGPGenerator/WebContent/templates/";
	protected List<Prism> prisms = new ArrayList<Prism>();
	protected List<Util> utils = new ArrayList<Util>();
	protected Set<Independent> independents = new TreeSet<Independent>();
	protected List<DBDefinitionGenerator> dbDefinitionGenerators = new ArrayList<DBDefinitionGenerator>();
	protected String dbName;
	protected TestSuite projectTestSuite = new TestSuite();
	protected List<ConfigFile> configFiles = new ArrayList<ConfigFile>();
	protected Set<IndependentConfig> independentConfigs = new TreeSet<IndependentConfig>();
	protected List<Domain> domains = new ArrayList<Domain>();
	protected List<String> domainNames = new ArrayList<>();
	protected String dbPrefix = "";
	protected String dbUsername = "root";
	protected String dbPassword = "";
	protected String dbType = "MariaDB";
	protected boolean emptypassword = false;
	protected EasyUIHomePagePI homepage;
	protected JumpHomePage jumphomepage = new JumpHomePage();
	protected String sgsSource;
	protected String sqlSource;
	protected String label;
	protected List<TwoDomainsDBDefinitionGenerator> myTwoDBGenerators = new ArrayList<TwoDomainsDBDefinitionGenerator>();
	protected List<List<Domain>> dataDomains = new ArrayList<>();
	protected String excelTemplateName = "";
	protected String excelTemplateFolder = "";
	protected String title = "";
	protected String subTitle = "";
	protected String footer = "";
	protected String crossOrigin = "";
	protected String resolution = "high";
	protected String domainSuffix = "domain";
	protected String daoSuffix = "dao";
	protected String daoimplSuffix = "dao";
	protected String serviceSuffix = "service";
	protected String serviceimplSuffix = "service";
	protected String controllerSuffix = "controller";
	protected String domainNamingSuffix = "";
	protected String controllerNamingSuffix = "Controller";
	protected String language = "chinese";
	protected String schema = "normal";
	protected String frontBaseApi = "";
	protected List<org.light.core.Module> modules = new ArrayList<>();
	protected List<LayoutComb> layoutCombs = new ArrayList<>();
	protected List<ReportComb> reportCombs = new ArrayList<>();
	protected Nav nav;
	protected String computerLanguage = "go";
	protected RouterGenerator routerg;
	protected HandlerGenerator handlerg;
	protected InitDBGenerator initdbg = new InitDBGenerator();
	protected CodeGoGenerator codegog = new CodeGoGenerator();
	protected ErrorGoGenerator errorgog = new ErrorGoGenerator();
	protected ConfigGoGenerator configgog = new ConfigGoGenerator();
	protected ConfigYamlGenerator configyamlg;
	protected ServerGoGenerator servergog;
	protected CorsGenerator corsg = new CorsGenerator();
	protected boolean sqlCommentsOn = false;	
	protected String originalExcelTemplateName;
	protected String frontendUi = "vueElNode14";
	protected String backendUi = "easyUi";
	protected List<ManyToManyCandidate> mtmCandidates = new ArrayList<>();
	protected List<List<ManyToManyCandidate>> mtmCandidatesValues = new ArrayList<>();
	
	public List<List<ManyToManyCandidate>> getMtmCandidatesValues() {
		return mtmCandidatesValues;
	}

	public void setMtmCandidatesValues(List<List<ManyToManyCandidate>> mtmCandidatesValues) {
		this.mtmCandidatesValues = mtmCandidatesValues;
	}
	
	public void addMtmCandidateValues(List<ManyToManyCandidate> mtmCandidatesValues) {
		this.mtmCandidatesValues.add(mtmCandidatesValues);
	}

	public List<ManyToManyCandidate> getMtmCandidates() {
		return mtmCandidates;
	}

	public void setMtmCandidates(List<ManyToManyCandidate> mtmCandidates) {
		this.mtmCandidates = mtmCandidates;
	}

	public void addMtmCandidate(ManyToManyCandidate mtmc) {
		this.mtmCandidates.add(mtmc);
	}

	public String getOriginalExcelTemplateName() {
		return originalExcelTemplateName;
	}

	public void setOriginalExcelTemplateName(String originalExcelTemplateName) {
		this.originalExcelTemplateName = originalExcelTemplateName;
	}

	public boolean isSqlCommentsOn() {
		return sqlCommentsOn;
	}

	public void setSqlCommentsOn(boolean sqlCommentsOn) {
		this.sqlCommentsOn = sqlCommentsOn;
	}

	public String getResolutmoion() {
		return resolution;
	}

	public void setResolution(String resolution) {
		this.resolution = resolution;
	}

	public String getSgsSource() {
		return sgsSource;
	}

	public void setSgsSource(String sgsSource) {
		this.sgsSource = sgsSource;
	}

	public String getSqlSource() {
		return sqlSource;
	}

	public void setSqlSource(String sqlSource) {
		this.sqlSource = sqlSource;
	}

	public boolean isEmptypassword() {
		return emptypassword;
	}

	public void setEmptypassword(boolean emptypassword) {
		this.emptypassword = emptypassword;
	}

	public Project() {
		super();
	}

	private void addIndependent(Independent idt) {
		this.independents.add(idt);
	}

	private void addIndependentConfig(IndependentConfig idc) {
		this.independentConfigs.add(idc);
	}

	public void decorateMentuItems() throws ValidateException{
		Set<ManyToMany> manyToManies = new TreeSet<ManyToMany>();
		for (Prism p : this.prisms) {
			manyToManies.addAll(p.getManyToManies());
		}
		Set<MenuItem> menuItems = new TreeSet<MenuItem>();
		if (this.nav!=null) {
			menuItems=nav.getNavMenuItems();
		}else {
			for (Prism p : this.prisms) {
				for (ManyToMany mtm : manyToManies) {
					MenuItem mi = new MenuItem("../pages/" + mtm.getStandardName().toLowerCase() + ".html",
							mtm.getStandardName(), mtm.getText());
					menuItems.add(mi);
				}
			}
		}
		for (ManyToMany mtm : manyToManies) {
			this.myTwoDBGenerators.add(mtm.toTwoDBGenerator());
		}
	}

	public ConfigFile findConfigFile(String standardName) {
		if (this.configFiles != null && this.configFiles.size() > 0) {
			for (ConfigFile c : this.configFiles) {
				if (c.getStandardName().equals(standardName))
					return c;
			}
		}
		return null;
	}

	public List<Util> getUtils() {
		return utils;
	}

	public void setUtils(List<Util> utils) {
		this.utils = utils;
	}

	public void addUtil(Util util) {
		this.utils.add(util);
	}

	public long getProjectId() {
		return projectId;
	}

	public void setProjectId(long projectId) {
		this.projectId = projectId;
	}

	public String getStandardName() {
		return standardName;
	}

	public void setStandardName(String standardName) {
		this.standardName = standardName;
	}

	public long getNamingId() {
		return namingId;
	}

	public void setNamingId(long namingId) {
		this.namingId = namingId;
	}

	public Naming getNaming() {
		return naming;
	}

	public void setNaming(Naming naming) {
		this.naming = naming;
	}

	public List<Prism> getPrisms() {
		return prisms;
	}

	public void setPrisms(List<Prism> prisms) {
		if (this.technicalstack == null || "".equals(this.technicalstack)
				|| "simple".equalsIgnoreCase(this.technicalstack)) {
			this.prisms = prisms;
			if (this.technicalstack == null || this.technicalstack.equals("")
					|| this.technicalstack.equalsIgnoreCase("sbmeu")) {
				this.prisms = prisms;
			}
		}
	}

	public void addPrism(Prism prism) {
		if (this.packageToken != null)
			prism.setPackageToken(this.packageToken);
		this.prisms.add(prism);
	}

	public String getPackageToken() {
		return packageToken;
	}

	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
		for (Util u : this.utils) {
			u.setPackageToken(packageToken);
		}
	}


	private boolean containsLoginModule() {
		Set<String> moduleNames = this.getModuleNames();
		if (moduleNames.contains("SimpleAuth")) return true;
		else return false;
	}

	public void generateMariaDBToolsFiles(boolean genFormatted,String exportStr) throws Exception {
		decorateMentuItems();
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		StringBuilder sql = new StringBuilder();
		boolean createNew = true;
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDBSql(createNew, this.sqlCommentsOn,exportStr)).append("\n");
			if (createNew)
				createNew = false;
		}
		for (TwoDomainsDBDefinitionGenerator mtg : this.getMyTwoDBGenerators()) {
			sql.append(mtg.generateDBSql(this.getDbType(), this.sqlCommentsOn,exportStr));
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(SqlReflector.generateInsertSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmInsertSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						if (d.hasDomainId())
							sql.append(SqlReflector.generateUpdateSqlWithValue(d)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						if (d.hasDomainId())
							sql.append(SqlReflector.generateDeleteSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmDeleteSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		sql.append("\n");
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDropTableSqls(false,exportStr)).append("\n");
		}

		for (TwoDomainsDBDefinitionGenerator mtg : this.getMyTwoDBGenerators()) {
			if (StringUtil.isBlank(exportStr)||exports.contains(mtg.getMaster().getStandardName())) {
				sql.append(mtg.generateDropLinkTableSql());
			}
		}

		writeToFile(this.getProjectFolderPath() + "sql/" + this.getStandardName() + ".sql", sql.toString());

		copyExcelTemplates(genFormatted);
	}

	public void generateOracleDBToolsFiles(boolean genFormatted,String exportStr) throws Exception {
		decorateMentuItems();
		
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		
		StringBuilder sql = new StringBuilder();
		boolean createNew = false;
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDropTableSqls(createNew,exportStr));
		}
		
		for (TwoDomainsDBDefinitionGenerator mtg : this.myTwoDBGenerators) {
			OracleTwoDomainsDBDefinitionGenerator otg = OracleTwoDomainsDBDefinitionGenerator.toOracleTwoDomainsDBDefinitionGenerator(mtg);
			if (StringUtil.isBlank(exportStr)||exports.contains(otg.getMaster().getStandardName())) {
				sql.append(otg.generateDropLinkTableSql());
			}
		}

		sql.append("\n\n");

		sql.append("drop sequence COMMONSEQUENCE;").append("\n\n");
		sql.append("-- Create sequence").append("\n").append("create sequence COMMONSEQUENCE").append("\n")
				.append("minvalue 10000").append("\n").append("maxvalue 9999999999999999999999999999").append("\n")
				.append("start with 10000").append("\n").append("increment by 1").append("\n").append("cache 20;")
				.append("\n\n");

		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDBSql(createNew, this.sqlCommentsOn,exportStr)).append("\n");
		}
		for (TwoDomainsDBDefinitionGenerator mtg : this.myTwoDBGenerators) {
			OracleTwoDomainsDBDefinitionGenerator otg = OracleTwoDomainsDBDefinitionGenerator.toOracleTwoDomainsDBDefinitionGenerator(mtg);
			sql.append(otg.generateDBSql(this.getDbType(), this.sqlCommentsOn,exportStr));
		}

		// load initial data
		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(Oracle11gSqlReflector.generateInsertSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(Oracle11gSqlReflector.generateMtmInsertSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(Oracle11gSqlReflector.generateUpdateSqlWithValue(d)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(Oracle11gSqlReflector.generateDeleteSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmDeleteSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		sql.append("commit;\n");
		writeToFile(this.getProjectFolderPath() + "sql/" + this.standardName + ".sql", sql.toString());

		copyExcelTemplates(genFormatted);
	}

	public void generatePgDBToolsFiles(boolean genFormatted,String exportStr) throws Exception {
		decorateMentuItems();
		
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		
		StringBuilder sql = new StringBuilder();
		boolean createNew = true;
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDBSql(createNew, this.sqlCommentsOn,exportStr)).append("\n");
			if (createNew)
				createNew = false;
		}
		for (TwoDomainsDBDefinitionGenerator mtg : this.getMyTwoDBGenerators()) {
			sql.append(mtg.generateDBSql(this.getDbType(), this.sqlCommentsOn,exportStr));
		}

		sql.append("\n");
		for (Domain d : getDomains()) {
			if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
				if (!(d instanceof org.light.domain.Enum)) {
					sql.append(PgsqlReflector.generateSetSerialVal10000(d)).append("\n");
				}
			}
		}
		sql.append("\n");

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(SqlReflector.generateInsertSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmInsertSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						if (d.hasDomainId())
							sql.append(SqlReflector.generateUpdateSqlWithValue(d)).append("\n");
					}
				}
			}
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						if (d.hasDomainId())
							sql.append(SqlReflector.generateDeleteSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmDeleteSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		sql.append("\n");
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDropTableSqls(false,exportStr)).append("\n");
		}

		for (TwoDomainsDBDefinitionGenerator mtg : this.getMyTwoDBGenerators()) {
			if (StringUtil.isBlank(exportStr)||exports.contains(mtg.getMaster().getStandardName())) {
				sql.append(mtg.generateDropLinkTableSql());
			}
		}

		writeToFile(this.getProjectFolderPath() + "sql/" + this.getStandardName() + ".sql", sql.toString());

		copyExcelTemplates(genFormatted);
	}

	public void generateProjectFiles(Boolean ignoreWarning, Boolean genFormatted, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl, String exportStr) throws Exception {
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		if (this.dbType == null || "".equals(this.dbType) || "mysql".equalsIgnoreCase(this.dbType)
				|| "mariadb".equalsIgnoreCase(this.dbType) || "postgresql".equalsIgnoreCase(this.dbType) || "pgsql".equalsIgnoreCase(this.dbType)|| "oracle".equalsIgnoreCase(this.dbType)) {
			ValidateInfo info = this.validate(ignoreWarning);
			if (info.success(ignoreWarning) == false) {
				throw new ValidateException(info);
			}
			try {
				decorateMentuItems();
				String srcfolderPath = this.getProjectFolderPath();
				if ("normal".equalsIgnoreCase(this.getSchema())) {
					for (Prism ps : this.prisms) {
						if (StringUtil.isBlank(exportStr) || exports.contains(ps.getDomain().getStandardName())){
							Set<Domain> existsSlaveDomains = new TreeSet<>();
							for (ManyToMany mtm : ps.getManyToManies()) {					
								existsSlaveDomains.add(mtm.getSlave());
							}

							for (ManyToMany mtm:ps.getManyToManies()) {
								EasyUIMtmPI mpage = mtm.getEuPI();
								mpage.setTechnicalStack(this.technicalstack);
								mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
								mpage.setNav(this.nav);
								mpage.generatePIFiles(srcfolderPath);
							}
							ps.setFolderPath(this.getProjectFolderPath());
							ps.generatePrismFiles(ignoreWarning, genUi, genController, genService, genServiceImpl, genDao,
									genDaoImpl);						
						}
					}
					
					Domain sampleDomain = this.getDomains().get(0);
					if (this.containsAuth()) {
						LoginServiceImplGenerator lsig = new LoginServiceImplGenerator();
						lsig.setDomains(this.getDomains());
						List<ManyToMany> mtms = new ArrayList<>();
						mtms.addAll(this.getMtms());
						lsig.setMtms(mtms);
						lsig.setLayouts(this.getLayoutCombs());
						lsig.setReports(this.getReportCombs());
						if (this.getModules()!=null && this.getModules().size()>0) {
							for (org.light.core.Module m:this.getModules()) {
								if (m instanceof SimpleAuthModule) {
									SimpleAuthModule sam = (SimpleAuthModule)m;
									lsig.setUserDomain(sam.getUserDomain());
									lsig.setRoleDomain(sam.getRoleDomain());
									lsig.setPrivilegeDomain(sam.getPrivilegeDomain());
								}
							}
						}
												
						writeToFile(this.getProjectFolderPath() + packagetokenToFolder(sampleDomain.getPackageToken())+packagetokenToFolder(sampleDomain.getServiceimplSuffix()) 
						+ lsig.getFileName(), lsig.generateUtilString());
					}

					
					writeToFile(this.getProjectFolderPath()+"middlewares/" + this.corsg.getFileName(),this.corsg.generateUtilString());
					
					writeToFile(this.getProjectFolderPath() + this.servergog.getFileName(),this.servergog.generateString());
					
					String routerPath = this.getProjectFolderPath()
							+ "router/";
					this.routerg.setSampleDomain(this.domains.get(0));
					writeToFile(routerPath + this.routerg.getFileName(),this.routerg.generateRouterString());

					String handlerPath = this.getProjectFolderPath()
							+ packagetokenToFolder(this.getPackageToken()+"."+this.getControllerSuffix());
					writeToFile(handlerPath + this.handlerg.getFileName(),this.handlerg.generateString());
					
					String initdbPath = this.getProjectFolderPath()
							+ "database/";
					this.initdbg.setSampleDomain(sampleDomain);
					boolean isDummy = true;
					for (Domain d: this.domains) {
						if (!(d instanceof org.light.domain.Enum)) isDummy = false;
					}
					this.initdbg.setDummy(isDummy);
					writeToFile(initdbPath + this.initdbg.getFileName(),this.initdbg.generateString());
					
					String confPath = this.getProjectFolderPath() + "conf/";
					writeToFile(confPath + this.configyamlg.getFileName(),this.configyamlg.generateString());
					
					String configPath = this.getProjectFolderPath() + "config/";
					writeToFile(configPath + this.configgog.getFileName(),this.configgog.generateString());
					
					String errorCodePath = this.getProjectFolderPath() + "pkg/errno/";
					writeToFile(errorCodePath + this.codegog.getFileName(),this.codegog.generateString());
					writeToFile(errorCodePath + this.errorgog.getFileName(),this.errorgog.generateString());
					
					for (Util u : utils) {
						String utilPath = this.getProjectFolderPath()
								+ packagetokenToFolder(u.getPackageToken()) + "utils/";
						writeToFile(utilPath + u.getFileName(), u.generateUtilString());
					}

					for (Independent idt : this.independents) {
						String idtPath = this.getProjectFolderPath() 
								+ packagetokenToFolder(idt.getPackageToken());
						writeToFile(idtPath + idt.getFileName(), idt.generateImplString());
					}
					
					if (this.modules!=null&& this.modules.size()>0) {
						for (int i=0;i<this.modules.size();i++) {
							if (this.modules.get(i) instanceof SimpleAuthModule) {
								if (StringUtil.isBlank(exportStr) || exports.contains(this.modules.get(i).getStandardName())){
									SimpleAuthModule sam = (SimpleAuthModule)this.modules.get(i);
									sam.generateModuleFiles(this.getProjectFolderPath(),ignoreWarning,genFormatted,genUi,genController,genService,genServiceImpl,genDao,genDaoImpl,exportStr);
								}
							}						
						}
					}
					
					for (LayoutComb lcb : this.layoutCombs) {
						if (StringUtil.isBlank(exportStr) || exports.contains(lcb.getStandardName())){
							lcb.generateCombFiles(this.getProjectFolderPath());
						}
					}
					
					for (ReportComb rcb : this.reportCombs) {
						if (StringUtil.isBlank(exportStr) || exports.contains(rcb.getStandardName())){
							rcb.generateCombFiles(this.getProjectFolderPath());
						}
					}

					String homePath = this.getProjectFolderPath();	
					String domainPath = homePath
							+ packagetokenToFolder(sampleDomain.getPackageToken()) + sampleDomain.getDomainSuffix()+"/";
					DateTimeAndDateGoGenerator dadgg = new DateTimeAndDateGoGenerator(sampleDomain);
					writeToFile(domainPath + dadgg.getFileName(), dadgg.generateStatementList().getContent());
					
					String utilsPath = homePath
							+ packagetokenToFolder(sampleDomain.getPackageToken()) + "utils/";
					DateTimeUtilGenerator dtug = new DateTimeUtilGenerator(sampleDomain);
					writeToFile(utilsPath + dtug.getFileName(), dtug.generateStatementList().getContent());

					if (genUi) {
						if (this.containsLoginModule()) {
							this.jumphomepage.setJumpFolder("login");
						}
						writeToFile(homePath + "index.html", this.jumphomepage.generateIncludeString());
						String templateIndexFolder = this.getProjectFolderPath() + "template/";
						writeToFile(templateIndexFolder + "index.html", this.jumphomepage.generateIncludeString());
					}
	
					if (genUi) {
						this.homepage.generatePIFiles(this.getProjectFolderPath());
					}
					
					copyHtmlSources(genUi);
					copyExcelTemplates(genFormatted);

					for (IndependentConfig idc : this.independentConfigs) {
						writeToFile(this.getProjectFolderPath() + idc.getFolder() + idc.getFileName(),
								idc.generateImplString());
					}

					if ("oracle".equalsIgnoreCase(this.dbType)) this.writeOracleSql(this.getProjectFolderPath(),exportStr);
					else  this.writeSql(this.getProjectFolderPath(),exportStr);
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw e;
			}
		} else {
			ValidateInfo info = new ValidateInfo();
			info.addCompileError("未支持项目所用数据库。");
			throw new ValidateException(info);
		}
	}
	
	public void writeSql( String projectFolderPath,String exportStr) throws Exception{
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		
		StringBuilder sql = new StringBuilder();
		boolean createNew = true;
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDBSql(createNew,this.sqlCommentsOn,exportStr)).append("\n");
			if (createNew)
				createNew = false;
		}
		for (TwoDomainsDBDefinitionGenerator mtg : this.myTwoDBGenerators) {
			sql.append(mtg.generateDBSql(this.getDbType(),this.sqlCommentsOn,exportStr));
		}
		
		if ("postgresql".equalsIgnoreCase(this.dbType) || "pgsql".equalsIgnoreCase(this.dbType)) {
			sql.append("\n");
			for (Domain d : getDomains()) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(PgsqlReflector.generateSetSerialVal10000(d)).append("\n");
					}
				}
			}
			sql.append("\n");
		}

		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (StringUtil.isBlank(exportStr)||exports.contains(d.getStandardName())) {
					if (!(d instanceof org.light.domain.Enum)) {
						sql.append(SqlReflector.generateInsertSqlWithValue(d)).append("\n");
					}
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					if (StringUtil.isBlank(exportStr)||exports.contains(mtm.getMaster().getStandardName())) {
						sql.append(SqlReflector.generateMtmInsertSqlWithValues(mtm)).append("\n");
					}
				}
			}
		}

		writeToFile(projectFolderPath + "sql/" + this.getStandardName() + ".sql", sql.toString());
	}
	
	public void writeOracleSql(String projectFolderPath,String exportStr) throws Exception{
		StringBuilder sql = new StringBuilder();
		boolean createNew = false;
		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDropTableSqls(createNew,exportStr));
		}

		for (TwoDomainsDBDefinitionGenerator mtg : this.myTwoDBGenerators) {
			OracleTwoDomainsDBDefinitionGenerator otg = OracleTwoDomainsDBDefinitionGenerator.toOracleTwoDomainsDBDefinitionGenerator(mtg);
			sql.append(otg.generateOracleDropLinkTableSql());
		}

		sql.append("\n\n");

		sql.append("drop sequence COMMONSEQUENCE;").append("\n\n");
		sql.append("-- Create sequence").append("\n").append("create sequence COMMONSEQUENCE").append("\n")
				.append("minvalue 10000").append("\n").append("maxvalue 9999999999999999999999999999")
				.append("\n").append("start with 10000").append("\n").append("increment by 1").append("\n")
				.append("cache 20;").append("\n\n");

		for (DBDefinitionGenerator dbd : dbDefinitionGenerators) {
			sql.append(dbd.generateDBSql(createNew, this.sqlCommentsOn,exportStr)).append("\n");
		}
		for (TwoDomainsDBDefinitionGenerator mtg : this.myTwoDBGenerators) {
			OracleTwoDomainsDBDefinitionGenerator otg = OracleTwoDomainsDBDefinitionGenerator.toOracleTwoDomainsDBDefinitionGenerator(mtg);
			sql.append(otg.generateDBSql(this.getDbType(), this.sqlCommentsOn,exportStr));
		}

		// load initial data
		for (List<Domain> dataDomains : this.getDataDomains()) {
			sql.append("\n");
			for (Domain d : dataDomains) {
				if (!(d instanceof org.light.domain.Enum)) {
					sql.append(Oracle11gSqlReflector.generateInsertSqlWithValue(d)).append("\n");
				}
			}

			for (Domain d : dataDomains) {
				for (ManyToMany mtm : d.getManyToManies()) {
					sql.append(Oracle11gSqlReflector.generateMtmInsertSqlWithValues(mtm)).append("\n");
				}
			}
		}
		sql.append("commit;\n");
		writeToFile(projectFolderPath + "sql/" + this.standardName + ".sql", sql.toString());
	}

	public String getSourceFolderPath() {
		return sourceFolderPath;
	}

	public void setSourceFolderPath(String sourceFolderPath) {
		this.sourceFolderPath = sourceFolderPath;
	}

	public void generateProjectZip(Boolean ignoreWarning, Boolean genFormatted, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl,String exportStr) throws Exception {
		delAllFile(this.folderPath + this.standardName + ".zip");
		delFolder(this.getProjectFolderPath());
		File f = new File(this.getProjectFolderPath());
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		f.mkdirs();
		if ("DBTools".equalsIgnoreCase(this.getSchema())) {
			if ("mariadb".equalsIgnoreCase(this.getDbType())||"mysql".equalsIgnoreCase(this.getDbType())) {
				generateMariaDBToolsFiles(genFormatted,exportStr);
			}else if ("oracle".equalsIgnoreCase(this.getDbType())) {
				generateOracleDBToolsFiles(genFormatted,exportStr);
			} else if ("postgresql".equalsIgnoreCase(this.getDbType())||"pgsql".equalsIgnoreCase(this.getDbType())) {
				generatePgDBToolsFiles(genFormatted,exportStr);
			}			
		}else if ("DataDummy".equalsIgnoreCase(this.getSchema())) {
			generateDataDummyProjectFiles(ignoreWarning, genFormatted, genUi, genController, genService, genServiceImpl, genDao,
					genDaoImpl,exportStr);
		}else if (this.getTechnicalstack().equalsIgnoreCase("simple")) {
			generateProjectFiles(ignoreWarning, genFormatted, genUi, genController, genService, genServiceImpl, genDao,
					genDaoImpl,exportStr);
		} 
		ZipCompressor compressor = new ZipCompressor(this.folderPath + this.standardName + ".zip");
		compressor.compressExe(this.getProjectFolderPath());
		delFolder(this.getProjectFolderPath());
	}

	public String getFolderPath() {
		return this.folderPath;
	}

	public String getProjectFolderPath() {
		if (this.getStandardName() != null && !"".equals(this.getStandardName())) {
			return folderPath + this.getStandardName() + "/";
		} else
			return folderPath;
	}

	public void setFolderPath(String folderPath) {
		this.folderPath = folderPath;
	}

	public static String packagetokenToFolder(String packageToken) {
		String folder = "";
		if (packageToken != null)
			folder = packageToken.replace('.', '/');
		folder += "/";
		return folder;
	}

	public static String folderToPackageToken(String folder) {
		String packagetoken = folder.replace('/', '.');
		if (packagetoken.charAt(packagetoken.length() - 1) == '.')
			packagetoken = packagetoken.substring(0, packagetoken.length() - 1);
		return packagetoken;
	}

	public List<DBDefinitionGenerator> getDbDefinitionGenerators() {
		return dbDefinitionGenerators;
	}

	public void setDbDefinitionGenerators(List<DBDefinitionGenerator> dbDefinitionGenerators) {
		this.dbDefinitionGenerators = dbDefinitionGenerators;
	}

	public void addDBDefinitionGenerator(DBDefinitionGenerator generator) {
		this.dbDefinitionGenerators.add(generator);
	}

	public String getDbName() {
		return dbName;
	}

	public void setDbName(String dbName) {
		this.dbName = dbName;
	}

	public TestSuite getProjectTestSuite() {
		return projectTestSuite;
	}

	public void setProjectTestSuite(TestSuite projectTestSuite) {
		this.projectTestSuite = projectTestSuite;
	}

	public void addTestSuite(TestSuite testSuite) {
		this.projectTestSuite.testSuites.add(testSuite);
	}

	public void addTestCase(TestCase testCase) {
		this.projectTestSuite.testCases.add(testCase);
	}

	public void addTestCases(List<TestCase> testCases) {
		this.projectTestSuite.testCases.addAll(testCases);
	}

	public List<ConfigFile> getConfigFiles() {
		return configFiles;
	}

	public void setConfigFiles(List<ConfigFile> configFiles) {
		this.configFiles = configFiles;
	}

	public void addConfigFile(ConfigFile configFile) {
		this.configFiles.add(configFile);
	}

	public void addConfigFiles(List<ConfigFile> configFiles) {
		this.configFiles.addAll(configFiles);
	}

	public static void zipFile(File inFile, ZipOutputStream zos, String dir) throws IOException {
		if (inFile.isDirectory()) {
			File[] files = inFile.listFiles();
			for (File file : files)
				zipFile(file, zos, dir + "/" + inFile.getName());
		} else {
			String entryName = null;
			if (!"".equals(dir))
				entryName = dir + "/" + inFile.getName();
			else
				entryName = inFile.getName();
			ZipEntry entry = new ZipEntry(entryName);
			zos.putNextEntry(entry);
			InputStream is = new FileInputStream(inFile);
			int len = 0;
			while ((len = is.read()) != -1)
				zos.write(len);
			is.close();
		}
	}

	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
				delFolder(path + "/" + tempList[i]);// 再删除空文件夹
				flag = true;
			}
		}
		return flag;
	}

	public ValidateInfo validate(Boolean ignoreWarning) {
		ValidateInfo info = new ValidateInfo();
		for (Domain d : this.domains) {
			ValidateInfo v = d.validate(this.getDbType());
			if (v.success(ignoreWarning) == false) {
				info.setSuccess(false);
				info.addAllCompileErrors(v.getCompileErrors());
				info.addAllCompileWarnings(v.getCompileWarnings());
			}
		}
		for (Prism ps : this.prisms) {
			ValidateInfo v = ps.validate(ignoreWarning);
			info.addAllCompileErrors(v.getCompileErrors());
			info.addAllCompileWarnings(v.getCompileWarnings());
		}
		return info;
	}

	public List<Domain> getDomains() {
		return domains;
	}

	public boolean updateDomain(int pos, Domain domain) {
		if (this.domains != null && this.domains.size() == pos - 1) {
			this.domains.add(domain);
			return true;
		} else if (this.domains != null && this.domains.size() > pos) {
			this.domains.set(pos, domain);
			return true;
		}
		return false;
	}

	public void setDomains(List<Domain> domains) throws Exception {
		for (Domain d : domains) {
			this.addDomain(d);
		}
	}

	public void addDomain(Domain domain) throws Exception {
		if (this.getDbPrefix() != null && !this.getDbPrefix().equals("")) {
			domain.setDbPrefix(this.getDbPrefix());
		}
		this.domains.add(domain);
	}

	public String getDbPrefix() {
		return dbPrefix;
	}

	public void setDbPrefix(String dbPrefix) {
		this.dbPrefix = dbPrefix;
		for (Domain d : this.getDomains()) {
			d.setDbPrefix(dbPrefix);
		}
		for (Prism p : this.getPrisms()) {
			p.getDomain().setDbPrefix(dbPrefix);
		}

	}

	public String getTechnicalstack() {
		return technicalstack;
	}

	public void setTechnicalstack(String technicalstack) {
		this.technicalstack = technicalstack;
	}

	public JumpHomePage getJumphomepage() {
		return jumphomepage;
	}

	public void setJumphomepage(JumpHomePage jumphomepage) {
		this.jumphomepage = jumphomepage;
	}

	public String getDbUsername() {
		return dbUsername;
	}

	public void setDbUsername(String dbUsername) {
		this.dbUsername = dbUsername;
	}

	public String getDbPassword() {
		return dbPassword;
	}

	public void setDbPassword(String dbPassword) {
		this.dbPassword = dbPassword;
	}

	public void replaceConfigFile(ConfigFile cf) {
		if (cf != null && this.configFiles != null) {
			if (this.configFiles.size() == 0 || !this.configFiles.contains(cf.getStandardName())) {
				this.configFiles.add(cf);
				return;
			}
			for (int i = 0; i < this.configFiles.size(); i++) {
				if (this.configFiles.get(i).getStandardName().equals(cf.getStandardName())) {
					this.configFiles.remove(i);
					this.configFiles.add(cf);
				}
			}
		}
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public String getText() {
		if (this.label != null && !this.label.equals(""))
			return this.label;
		else
			return this.standardName;
	}

	public void writeToFile(String filePath, String content) throws Exception {
		File f = new File(filePath);
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		f.createNewFile();
		try (Writer fw = new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(f.getAbsolutePath()), "UTF-8"))) {
			fw.write(content, 0, content.length());
		}
	}

	public List<TwoDomainsDBDefinitionGenerator> getMyTwoDBGenerators() {
		return myTwoDBGenerators;
	}

	public void setMyTwoDBGenerators(List<TwoDomainsDBDefinitionGenerator> myTwoDBGenerators) {
		this.myTwoDBGenerators = myTwoDBGenerators;
	}

	public String getDbType() {
		return dbType;
	}

	public void setDbType(String dbType) {
		this.dbType = dbType;
	}

	public String toString() {
		return JSONObject.fromObject(this).toString();
	}

	public static File createPathFile(String path) {
		try {
			File f = new File(path);
			if (!f.getParentFile().exists()) {
				f.getParentFile().mkdirs();
			}
			f.createNewFile();
			return f;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public List<List<Domain>> getDataDomains() {
		return dataDomains;
	}

	public void setDataDomains(List<List<Domain>> dataDomains) {
		this.dataDomains = dataDomains;
	}

	public void addDataDomains(List<Domain> datas) {
		this.dataDomains.add(datas);
	}

	public String getExcelTemplateName() {
		return excelTemplateName;
	}

	public void setExcelTemplateName(String excelTemplateName) {
		this.excelTemplateName = excelTemplateName;
	}

	public String getExcelTemplateFolder() {
		return excelTemplateFolder;
	}

	public void setExcelTemplateFolder(String excelTemplateFolder) {
		this.excelTemplateFolder = excelTemplateFolder;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getSubTitle() {
		return subTitle;
	}

	public void setSubTitle(String subTitle) {
		this.subTitle = subTitle;
	}

	public String getFooter() {
		return footer;
	}

	public void setFooter(String footer) {
		this.footer = footer;
	}

	public String getCrossOrigin() {
		return crossOrigin;
	}

	public void setCrossOrigin(String crossOrigin) {
		this.crossOrigin = crossOrigin;
	}

	public Set<Independent> getIndependents() {
		return independents;
	}

	public void setIndependents(Set<Independent> independents) {
		this.independents = independents;
	}

	public Set<IndependentConfig> getIndependentConfigs() {
		return independentConfigs;
	}

	public void setIndependentConfigs(Set<IndependentConfig> independentConfigs) {
		this.independentConfigs = independentConfigs;
	}

	public String getDaoSuffix() {
		return daoSuffix;
	}

	public void setDaoSuffix(String daoSuffix) {
		this.daoSuffix = daoSuffix;
	}

	public String getServiceSuffix() {
		return serviceSuffix;
	}

	public void setServiceSuffix(String serviceSuffix) {
		this.serviceSuffix = serviceSuffix;
	}

	public String getServiceimplSuffix() {
		return serviceimplSuffix;
	}

	public void setServiceimplSuffix(String serviceimplSuffix) {
		this.serviceimplSuffix = serviceimplSuffix;
	}

	public String getControllerSuffix() {
		return controllerSuffix;
	}

	public void setControllerSuffix(String controllerSuffix) {
		this.controllerSuffix = controllerSuffix;
	}

	public String getDomainNamingSuffix() {
		return domainNamingSuffix;
	}

	public void setDomainNamingSuffix(String domainNamingSuffix) {
		this.domainNamingSuffix = domainNamingSuffix;
	}

	public String getControllerNamingSuffix() {
		return controllerNamingSuffix;
	}

	public void setControllerNamingSuffix(String controllerNamingSuffix) {
		this.controllerNamingSuffix = controllerNamingSuffix;
	}

	public String getDaoimplSuffix() {
		return daoimplSuffix;
	}

	public void setDaoimplSuffix(String daoimplSuffix) {
		this.daoimplSuffix = daoimplSuffix;
	}

	public String getDomainSuffix() {
		return domainSuffix;
	}

	public void setDomainSuffix(String domainSuffix) {
		this.domainSuffix = domainSuffix;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}

	public String getSchema() {
		return schema;
	}

	public void setSchema(String schema) {
		this.schema = schema;
	}

	public String getFrontBaseApi() {
		return frontBaseApi;
	}

	public void setFrontBaseApi(String frontBaseApi) {
		this.frontBaseApi = frontBaseApi;
	}

	public void addModule(org.light.core.Module m) {
		this.modules.add(m);
	}
	
	public Set<String> getModuleNames() {
		Set<String> moduleNames = new TreeSet<>();
		for(org.light.core.Module m: this.modules) {
			moduleNames.add(m.getStandardName());
		}
		return moduleNames;
	}

	public String getResolution() {
		return resolution;
	}
	
	public void removeAllModules() {
		this.modules.clear();
	}
	
	public void addLayoutComb(LayoutComb layoutComb) {
		this.layoutCombs.add(layoutComb);
	}
	
	public void addReportComb(ReportComb reportComb) {
		this.reportCombs.add(reportComb);
	}
	
	public void setReportComb(int pos,ReportComb report) {
		this.reportCombs.set(pos, report);
	}

	public Nav getNav() {
		return nav;
	}

	public void setNav(Nav nav) {
		this.nav = nav;
	}

	public EasyUIHomePagePI getHomepage() {
		return homepage;
	}

	public void setHomepage(EasyUIHomePagePI homepage) {
		this.homepage = homepage;
	}

	public List<String> getDomainNames() {
		return domainNames;
	}

	public void setDomainNames(List<String> domainNames) {
		this.domainNames = domainNames;
	}
	
	public void addDomainName(String domainName) {
		this.domainNames.add(domainName);
	}

	public String getComputerLanguage() {
		return computerLanguage;
	}

	public void setComputerLanguage(String computerLanguage) {
		this.computerLanguage = computerLanguage;
	}

	public RouterGenerator getRouterg() {
		return routerg;
	}

	public void setRouterg(RouterGenerator routerg) {
		this.routerg = routerg;
	}

	public HandlerGenerator getHandlerg() {
		return handlerg;
	}

	public void setHandlerg(HandlerGenerator handlerg) {
		this.handlerg = handlerg;
	}

	public InitDBGenerator getInitdbg() {
		return initdbg;
	}

	public void setInitdbg(InitDBGenerator initdbg) {
		this.initdbg = initdbg;
	}

	public CodeGoGenerator getCodegog() {
		return codegog;
	}

	public void setCodegog(CodeGoGenerator codegog) {
		this.codegog = codegog;
	}

	public ErrorGoGenerator getErrorgog() {
		return errorgog;
	}

	public void setErrorgog(ErrorGoGenerator errorgog) {
		this.errorgog = errorgog;
	}

	public ConfigGoGenerator getConfiggog() {
		return configgog;
	}

	public void setConfiggog(ConfigGoGenerator configgog) {
		this.configgog = configgog;
	}

	public ConfigYamlGenerator getConfigyamlg() {
		return configyamlg;
	}

	public void setConfigyamlg(ConfigYamlGenerator configyamlg) {
		this.configyamlg = configyamlg;
	}

	public ServerGoGenerator getServergog() {
		return servergog;
	}

	public void setServergog(ServerGoGenerator servergog) {
		this.servergog = servergog;
	}
	
	public void setLayoutComb(int pos,LayoutComb layoutComb) {
		this.layoutCombs.set(pos, layoutComb);
	}

	public List<LayoutComb> getLayoutCombs() {
		return layoutCombs;
	}

	public void setLayoutCombs(List<LayoutComb> layoutCombs) {
		this.layoutCombs = layoutCombs;
	}

	public CorsGenerator getCorsg() {
		return corsg;
	}

	public void setCorsg(CorsGenerator corsg) {
		this.corsg = corsg;
	}

	public void setReportCombs(List<ReportComb> reportCombs) {
		this.reportCombs = reportCombs;
	}

	public List<ReportComb> getReportCombs() {
		return reportCombs;
	}

	public List<org.light.core.Module> getModules() {
		return modules;
	}

	public void setModules(List<org.light.core.Module> modules) {
		this.modules = modules;
	}	
	
	public boolean containsAuth() {
		if (this.getModules()!=null&& this.getModuleNames().size()>0) {
			for (String mName:this.getModuleNames()) {
				if (mName.equalsIgnoreCase("SimpleAuth")) return true;
			}
		}
		return false;
	}

	public Set<ManyToMany> getMtms(){
		Set<ManyToMany> mtms = new TreeSet<>();
		for (Prism p:this.getPrisms()) {
			Set<ManyToMany> cmtms = p.getManyToManies();
			if (cmtms !=null&& cmtms.size()>0) mtms.addAll(cmtms);
		}
		return mtms;
	}
	
	public void copyExcelTemplates(boolean genFormatted) throws Exception{
		FileCopyer copy = new FileCopyer();
		if (!StringUtil.isBlank(this.getExcelTemplateName())) {
			File mF1 = new File(
					(this.getExcelTemplateFolder() + this.getExcelTemplateName()).replace("\\", "/"));
			File mF2 = new File(
					(this.getProjectFolderPath() + "exceltemplate/" + this.getExcelTemplateName())
							.replace("\\", "/"));
			if (mF1.exists()) {
				if (!mF2.getParentFile().exists()) {
					mF2.getParentFile().mkdirs();
				}
				if (!mF2.exists()) {
					mF2.createNewFile();
				}
				copy.copy(mF1.getPath(), mF2.getPath());
			}
			if (!StringUtil.isBlank(this.getOriginalExcelTemplateName())) {
				File mF3 = new File(
						(this.getExcelTemplateFolder() + this.getOriginalExcelTemplateName()).replace("\\", "/"));
				File mF4 = new File(
						(this.getProjectFolderPath() + "exceltemplate/" + this.getOriginalExcelTemplateName())
								.replace("\\", "/"));
				if (mF3.exists()) {
					if (!mF4.getParentFile().exists()) {
						mF4.getParentFile().mkdirs();
					}
					if (!mF4.exists()) {
						mF4.createNewFile();
					}
					copy.copy(mF3.getPath(), mF4.getPath());
				}
			}
			if (genFormatted && StringUtil.isBlank(this.originalExcelTemplateName)) {
				String genExcelFile = "Gen_formatted";
				String[] genExcelFiles = this.getExcelTemplateName().split("\\.");
				if (genExcelFiles != null && genExcelFiles.length > 0)
					genExcelFile = genExcelFiles[0] + "_formatted";
				ExcelWizard.outputExcelWorkBook(this,
						(this.getProjectFolderPath() + "exceltemplate/").replace("\\", "/"),
						genExcelFile + ".xls");
			}
		}
	}
	
	public void generateDataDummyProjectFiles(Boolean ignoreWarning, Boolean genFormatted, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl, String exportStr) throws Exception {
		List<String> exports = new ArrayList<>();
		String [] exportArr = exportStr.split(",");
		for (String str :exportArr) {
			exports.add(str);
		}
		if (this.dbType == null || "".equals(this.dbType) || "mysql".equalsIgnoreCase(this.dbType)
				|| "mariadb".equalsIgnoreCase(this.dbType) || "postgresql".equalsIgnoreCase(this.dbType) || "pgsql".equalsIgnoreCase(this.dbType)|| "oracle".equalsIgnoreCase(this.dbType)) {
			ValidateInfo info = this.validate(ignoreWarning);
			if (info.success(ignoreWarning) == false) {
				throw new ValidateException(info);
			}
			try {
				decorateMentuItems();
				String srcfolderPath = this.getProjectFolderPath();
				if ("datadummy".equalsIgnoreCase(this.getSchema())) {
					for (Prism ps : this.prisms) {
						if (StringUtil.isBlank(exportStr) || exports.contains(ps.getDomain().getStandardName())){
							Set<Domain> existsSlaveDomains = new TreeSet<>();
							for (ManyToMany mtm : ps.getManyToManies()) {					
								existsSlaveDomains.add(mtm.getSlave());
							}
							for (ManyToMany mtm:ps.getManyToManies()) {
								EasyUIMtmPI mpage = mtm.getEuPI();
								mpage.setTechnicalStack(this.technicalstack);
								mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
								mpage.setNav(this.nav);
								mpage.generatePIFiles(this.getProjectFolderPath());
							}
							ps.setFolderPath(this.getProjectFolderPath());
							ps.generateDummyPrismFiles(ignoreWarning, genUi, genController, genService, genServiceImpl, genDao,
									genDaoImpl);
						}
					}
					
					Domain sampleDomain = this.getDomains().get(0);
					
					if (this.containsAuth()) {
						org.light.core.Module mm = null;
						if (this.getModules()!=null && this.getModules().size()>0) {
							for (org.light.core.Module im:this.getModules()) {
								mm = im;
							}
						}
						if (StringUtil.isBlank(exportStr) || exports.contains(mm.getStandardName())){
							LoginServiceImplGenerator lsig = new LoginServiceImplGenerator();
							lsig.setDomains(this.getDomains());
							List<ManyToMany> mtms = new ArrayList<>();
							mtms.addAll(this.getMtms());
							lsig.setMtms(mtms);
							lsig.setLayouts(this.getLayoutCombs());
							lsig.setReports(this.getReportCombs());
							if (this.getModules()!=null && this.getModules().size()>0) {
								for (org.light.core.Module m:this.getModules()) {
									if (m instanceof SimpleAuthModule) {
										SimpleAuthModule sam = (SimpleAuthModule)m;
										lsig.setUserDomain(sam.getUserDomain());
										lsig.setRoleDomain(sam.getRoleDomain());
										lsig.setPrivilegeDomain(sam.getPrivilegeDomain());
									}
								}
							}
						
							writeToFile(srcfolderPath + packagetokenToFolder(sampleDomain.getPackageToken())+packagetokenToFolder(sampleDomain.getServiceimplSuffix()) 
							+ lsig.getFileName(), lsig.generateUtilString());
						}
					}	
					
					writeToFile(this.getProjectFolderPath()+"middlewares/" + this.corsg.getFileName(),this.corsg.generateUtilString());
					
					writeToFile(this.getProjectFolderPath() + this.servergog.getFileName(),this.servergog.generateString());
					
					String routerPath = this.getProjectFolderPath()
							+ "router/";
					this.routerg.setSampleDomain(sampleDomain);
					writeToFile(routerPath + this.routerg.getFileName(),this.routerg.generateRouterString());

					String handlerPath = this.getProjectFolderPath()
							+ packagetokenToFolder(this.getPackageToken()+"."+this.getControllerSuffix());
					writeToFile(handlerPath + this.handlerg.getFileName(),this.handlerg.generateString());
					
					String initdbPath = this.getProjectFolderPath()
							+ "database/";
					this.initdbg.setSampleDomain(sampleDomain);
					boolean isDummy = true;
					for (Domain d: this.domains) {
						if (!(d instanceof org.light.domain.Enum)) isDummy = false;
					}
					this.initdbg.setDummy(isDummy);
					writeToFile(initdbPath + this.initdbg.getFileName(),this.initdbg.generateString());
					
					String confPath = this.getProjectFolderPath() + "conf/";
					writeToFile(confPath + this.configyamlg.getFileName(),this.configyamlg.generateString());
					
					String configPath = this.getProjectFolderPath() + "config/";
					writeToFile(configPath + this.configgog.getFileName(),this.configgog.generateString());
					
					String errorCodePath = this.getProjectFolderPath() + "pkg/errno/";
					writeToFile(errorCodePath + this.codegog.getFileName(),this.codegog.generateString());
					writeToFile(errorCodePath + this.errorgog.getFileName(),this.errorgog.generateString());


					for (Independent idt : this.independents) {
						String idtPath = this.getProjectFolderPath() 
								+ packagetokenToFolder(idt.getPackageToken());
						writeToFile(idtPath + idt.getFileName(), idt.generateImplString());
					}
					
					if (this.modules!=null&& this.modules.size()>0) {
						for (int i=0;i<this.modules.size();i++) {
							if (this.modules.get(i) instanceof SimpleAuthModule) {
								if (StringUtil.isBlank(exportStr) || exports.contains(this.modules.get(i).getStandardName())){
									SimpleAuthModule sam = (SimpleAuthModule)this.modules.get(i);
									sam.generateDummyModuleFiles(this.getProjectFolderPath(),genUi, genController,
											genService, genServiceImpl, genDao, genDaoImpl);
								}
							}						
						}
					}
					
					for (LayoutComb lcb : this.layoutCombs) {
						if (StringUtil.isBlank(exportStr) || exports.contains(lcb.getStandardName())){
							lcb.generateCombFiles(this.getProjectFolderPath());
						}
					}
					
					for (ReportComb rcb : this.reportCombs) {
						if (StringUtil.isBlank(exportStr) || exports.contains(rcb.getStandardName())){
							rcb.generateCombFiles(this.getProjectFolderPath());
						}
					}

					String homePath = this.getProjectFolderPath();
					String domainPath = homePath
							+ packagetokenToFolder(sampleDomain.getPackageToken()) + sampleDomain.getDomainSuffix()+"/";
					DateTimeAndDateGoGenerator dadgg = new DateTimeAndDateGoGenerator(sampleDomain);
					writeToFile(domainPath + dadgg.getFileName(), dadgg.generateStatementList().getContent());
					
					String utilsPath = homePath
							+ packagetokenToFolder(sampleDomain.getPackageToken()) + "utils/";
					DateTimeUtilGenerator dtug = new DateTimeUtilGenerator(sampleDomain);
					writeToFile(utilsPath + dtug.getFileName(), dtug.generateStatementList().getContent());
					
					if (genUi) {
						if (this.containsLoginModule()) {
							this.jumphomepage.setJumpFolder("login");
						}
						writeToFile(homePath + "index.html", this.jumphomepage.generateIncludeString());
						String templateIndexFolder = this.getProjectFolderPath() + "template/";
						writeToFile(templateIndexFolder + "index.html", this.jumphomepage.generateIncludeString());
					}
	
					if (genUi) {
						this.homepage.generatePIFiles(this.getProjectFolderPath());
					}

					copyHtmlSources(genUi);
					copyExcelTemplates(genFormatted);
					
					for (Util u : utils) {
						String utilPath = this.getProjectFolderPath()
								+ packagetokenToFolder(u.getPackageToken()) + "utils/";
						writeToFile(utilPath + u.getFileName(), u.generateUtilString());
					}

					for (IndependentConfig idc : this.independentConfigs) {
						writeToFile(this.getProjectFolderPath() + idc.getFolder() + idc.getFileName(),
								idc.generateImplString());
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw e;
			}
		} else {
			ValidateInfo info = new ValidateInfo();
			info.addCompileError("未支持项目所用数据库。");
			throw new ValidateException(info);
		}
	}
	
	private void copyHtmlSources(boolean genUi) {
		FileCopyer copy = new FileCopyer();
		
		File tempfrom = new File(this.getSourceFolderPath() + "temp/");
		File tempto = new File(this.getProjectFolderPath() + "template/temp/");

		copy.dirFrom = tempfrom;
		copy.dirTo = tempto;
		copy.listFileInDir(tempfrom);
							
		if (genUi) {						
			File cssfrom = new File(this.getSourceFolderPath() + "css/");
			File cssto = new File(this.getProjectFolderPath() + "template/css/");

			copy.dirFrom = cssfrom;
			copy.dirTo = cssto;
			copy.listFileInDir(cssfrom);

			File jsfrom = new File(this.getSourceFolderPath() + "js/");
			File jsto = new File(this.getProjectFolderPath() + "template/js/");

			copy.dirFrom = jsfrom;
			copy.dirTo = jsto;
			copy.listFileInDir(jsfrom);

			File easyuifrom = new File(this.getSourceFolderPath() + "easyui/");
			File easyuito = new File(this.getProjectFolderPath() + "template/easyui/");

			copy.dirFrom = easyuifrom;
			copy.dirTo = easyuito;
			copy.listFileInDir(easyuifrom);

			File uploadjsfrom = new File(this.getSourceFolderPath() + "uploadjs/");
			File uploadjsto = new File(this.getProjectFolderPath() + "template/uploadjs/");

			copy.dirFrom = uploadjsfrom;
			copy.dirTo = uploadjsto;
			copy.listFileInDir(uploadjsfrom);
			
			File imagefrom = new File(this.getSourceFolderPath() + "images/");
			File imageto = new File(this.getProjectFolderPath() + "template/images/");

			copy.dirFrom = imagefrom;
			copy.dirTo = imageto;
			copy.listFileInDir(imagefrom);
			
			File echartsfrom = new File(this.getSourceFolderPath() + "echarts/");
			File echartsto = new File(this.getProjectFolderPath() + "template/echarts/");

			copy.dirFrom = echartsfrom;
			copy.dirTo = echartsto;
			copy.listFileInDir(echartsfrom);
			
			File fontsfrom = new File(this.getSourceFolderPath() + "fonts/");
			File fontsto = new File(this.getProjectFolderPath());

			copy.dirFrom = fontsfrom;
			copy.dirTo = fontsto;
			copy.listFileInDir(fontsfrom);
		}
	}

	public boolean clearLoginDataSimpleAuthModule() throws ValidateException{
		if (this.containsAuth()) {
			SimpleAuthModule sam = (SimpleAuthModule) this.modules.get(0);
			Domain userDomain = sam.getUserDomain();
			List<Domain> dcl = new ArrayList<>();
			if (userDomain.getDummyDb()!=null){
				for (Domain u : userDomain.getDummyDb()) {
					u.findFieldByFixedName("password").setFieldValue(u.findFieldByFixedName("userName").getFieldValue());
					u.findFieldByFixedName("loginFailure").setFieldValue("0");
					u.findFieldByFixedName("salt").setFieldValue("");
					dcl.add(u);
				}
				userDomain.setDummyDb(dcl);
			}
			
			List<List<Domain>> finalDataDomainList = new ArrayList<>();
			for (List<Domain> ds : this.dataDomains) {
				if (ds.size() > 0){
					Domain d1 = ds.get(0);
					if (d1.getStandardName().equals(userDomain.getStandardName())) {
						List<Domain> ddcl = new ArrayList<>();
						for (Domain u : ds) {
							u.findFieldByFixedName("password").setFieldValue(u.findFieldByFixedName("userName").getFieldValue());
							u.findFieldByFixedName("loginFailure").setFieldValue("0");
							u.findFieldByFixedName("salt").setFieldValue("");
							ddcl.add(u);
						}
						finalDataDomainList.add(ddcl);
					} else {
						finalDataDomainList.add(ds);
					}
				} else {
					finalDataDomainList.add(ds);
				}
			}
			this.setDataDomains(finalDataDomainList);
			sam.setDataDomains(finalDataDomainList);
			//sam.setUserDomain(userDomain);
		} else {
			throw new ValidateException("没有登录模块！");
		}
		return false;
	}

	public String getFrontendUi() {
		return frontendUi;
	}

	public void setFrontendUi(String frontendUi) {
		this.frontendUi = frontendUi;
	}

	public String getBackendUi() {
		return backendUi;
	}

	public void setBackendUi(String backendUi) {
		this.backendUi = backendUi;
	}
	
	public void setPureDbPrefix(String dbPrefix) {
		this.dbPrefix = dbPrefix;
	}
}